package com.info33.platform.doc.util;

import cn.hutool.core.io.FileUtil;
import com.itextpdf.text.pdf.PdfReader;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.xslf.usermodel.XMLSlideShow;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.StandardCopyOption;

/**
 * 计算文档页数
 *
 * @author yhr12
 */
public class FileUtils {

    /**
     * 计算pdf格式文档的页数
     *
     * @param filepath 文件路径
     * @return pagecount页数
     */
    public static int countPdfPage(String filepath) {
        PdfReader reader;
        try {
            reader = new PdfReader(filepath);
            return reader.getNumberOfPages();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 计算PPT格式文档的页数
     *
     * @param filePath 文件路径
     * @return pages 页数
     */
    public static int countPPTPage(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            return new HSLFSlideShow(fis).getSlides().size();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }


    /**
     * 计算PPTX格式文档的页数
     *
     * @param filePath
     * @return
     * @throws IOException
     */
    public static int countPPTXPage(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            return new XMLSlideShow(fis).getSlides().size();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 图片压缩至 512K 以下，并覆盖原图
     * 原图：原图名-yt.png
     *
     * @param imgFileUrl 原文件全路径
     */
    public static void compressPicCycle(
            String imgFileUrl) throws IOException {
        compressPicCycle(new File(imgFileUrl));
    }

    /**
     * 图片压缩至 512K 以下，并覆盖原图
     * 原图：原图名-yt.png
     *
     * @param imgFile 原文件
     */
    public static void compressPicCycle(
            File imgFile) throws IOException {
        compressPicCycle(imgFile, 512, 0.8, true);
    }

    /**
     * 图片压缩，并覆盖原图
     * 原图：原图名-yt.png
     * <p>
     * 1. copy 原图像
     * 2. 进行图片压缩递归，并覆盖原图
     *
     * @param imgFile     原文件
     * @param desFileSize 目标大小，单位 kb
     * @param accuracy    每次压缩的比例 如 0.8
     * @param copy        是否保留原图
     */
    public static void compressPicCycle(
            File imgFile,
            long desFileSize,
            double accuracy,
            Boolean copy) throws IOException {
        if (imgFile.length() <= desFileSize * 1024) {
            return;
        }
        // 保存原图
        if (Boolean.TRUE.equals(copy)) {
            FileUtil.copyFile(
                    imgFile,
                    new File(imgFile.getAbsolutePath() + "-yt.png"),
                    StandardCopyOption.REPLACE_EXISTING);
        }
        compressPicRecursion(imgFile, desFileSize, accuracy);
    }

    /**
     * 进行图片压缩递归，并覆盖原图
     *
     * @param imgFile     原文件
     * @param desFileSize 目标大小，单位 kb
     * @param accuracy    每次压缩的比例 如 0.8
     */
    private static void compressPicRecursion(
            File imgFile,
            long desFileSize,
            double accuracy) throws IOException {
        long fileSize = imgFile.length();
        // 判断大小,如果小于目标大小,不压缩
        if (fileSize <= desFileSize * 1024) {
            return;
        }
        // 计算宽高
        BufferedImage bim = ImageIO.read(imgFile);
        int desWidth = new BigDecimal(bim.getWidth())
                .multiply(BigDecimal.valueOf(accuracy))
                .intValue();
        int desHeight = new BigDecimal(bim.getHeight())
                .multiply(BigDecimal.valueOf(accuracy))
                .intValue();
        Thumbnails
                .of(imgFile)
                .size(desWidth, desHeight)
                .outputQuality(accuracy)
                .toFile(imgFile);
        // 如果不满足要求,递归直至满足要求
        compressPicRecursion(imgFile, desFileSize, accuracy);
    }

}
